/*
 * @Author: ygnnli 1585923072@qq.com
 * @Date: 2024-08-19 14:28:40
 * @LastEditors: ygnnli 1585923072@qq.com
 * @LastEditTime: 2024-08-28 10:54:01
 * @FilePath: /bitrpc/source/server/rpc_server.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "../common/dispatcher.hpp"
#include "../client/rpc_client.hpp"
#include "rpc_router.hpp"
#include "rpc_registry.hpp"
#include "rpc_topic.hpp"

namespace bitrpc
{
    namespace server
    {
        // 注册中心服务器 :只需要针对服务注册与发现请求进行处理即可
        class RegistryServer
        {
        public:
            using ptr = std::shared_ptr<RegistryServer>;
            RegistryServer(int port)
                : _pd_manager(std::make_shared<PDManager>()),
                  _dispatcher(std::make_shared<bitrpc::Dispatcher>())
            {
                auto service_cb = std::bind(&PDManager::onServiceRequest, _pd_manager.get(), std::placeholders::_1, std::placeholders::_2); // 服务回调
                _dispatcher->registerhandler<ServiceRequest>(MType::REQ_SERVICE, service_cb);                                               // 将服务回调注册到调度器中
                //ELOG("完成注册中心::服务回调注册");

                _server = bitrpc::ServerFactory::create(port);
                auto message_cb = std::bind(&bitrpc::Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2); // 消息回调
                _server->setMessageCallback(message_cb);                                                                                      // 将消息回调注册到服务器中
                //ELOG("完成注册中心::消息回调注册");

                auto close_cb = std::bind(&RegistryServer::onConnShutdown, this, std::placeholders::_1); // 关闭回调
                _server->setCloseCallback(close_cb);                                                     // 将关闭回调注册到服务器中
                //ELOG("完成注册中心::关闭回调注册");
            }
            // 启动服务器
            void start()
            {
                ELOG("启动服务器!");
                _server->start();
            }

        private:
            void onConnShutdown(const BaseConnection::ptr &conn)
            {
                _pd_manager->onConnShutdown(conn); // 处理关闭连接
            }

        private:
            PDManager::ptr _pd_manager;  // 注册发现管理器
            Dispatcher::ptr _dispatcher; // 调度器
            BaseServer::ptr _server;     // 服务器
        };

        class RpcServer
        {
        public:
            using ptr = std::shared_ptr<RpcServer>;
            // rpc——server端有两套地址信息：
            //   1. rpc服务提供端地址信息--必须是rpc服务器对外访问地址（云服务器---监听地址和访问地址不同）
            //   2. 注册中心服务端地址信息 -- 启用服务注册后，连接注册中心进行服务注册用的
            RpcServer(const Address &access_addr,
                      bool enableRegistry = false, const Address &registry_server_addr = Address())
                : _enableRegistry(enableRegistry), _access_addr(access_addr), _router(std::make_shared<bitrpc::server::RpcRouter>()), _dispatcher(std::make_shared<bitrpc::Dispatcher>())
            {
                if (enableRegistry)
                {
                    // 注册客户端中心
                    _reg_client = std::make_shared<client::RegistryClient>(registry_server_addr.first, registry_server_addr.second);
                }
                // 当前成员server是一个rpcserver，用于提供rpc服务的 rpc请求的回调函数
                auto _rpc_cb = std::bind(&bitrpc::server::RpcRouter::onRpcRequest, _router.get(), std::placeholders::_1, std::placeholders::_2); // router.get()获取RpcRouter对象的指针 绑定RpcRouter对象的onRpcRequest函数
                _dispatcher->registerhandler<bitrpc::RpcRequest>(bitrpc::MType::REQ_RPC, _rpc_cb);                                               // 注册RpcRequest类型的消息处理函数
                // 我们要监听的是内网地址,这里给的是外网地址,我们无法监听外网地址,所以我们监听的是rpc服务提供端地址的所有端口
                _server = bitrpc::ServerFactory::create(access_addr.second); // 监听的是rpc服务提供端地址的端口
                auto message_cb = std::bind(&bitrpc::Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2);
                _server->setMessageCallback(message_cb); // 设置消息回调函数
            }
            // 注册服务
            void registerMethod(const ServiceDescribe::ptr &service)
            {
                if (_enableRegistry)
                {
                    ELOG("服务中心开启，注册服务!");
                    _reg_client->registryMethod(service->method(), _access_addr); // 注册服务到注册中心
                }
                _router->registerMethod(service); // 注册服务到路由
            }

            void start()
            {
                ELOG("启动Service服务器!");
                _server->start();
            }

        private:
            bool _enableRegistry;                    // 是否启用服务注册
            Address _access_addr;                    // rpc服务提供端地址信息
            client::RegistryClient::ptr _reg_client; // 注册中心客户端
            RpcRouter::ptr _router;                  // 路由
            Dispatcher::ptr _dispatcher;             // 调度器
            BaseServer::ptr _server;                 // 服务器
        };

        class TopicServer
        {
        public:
            using ptr = std::shared_ptr<TopicServer>;
            TopicServer(int port)
                : _topic_manager(std::make_shared<TopicManager>()),
                  _dispatcher(std::make_shared<bitrpc::Dispatcher>())
            {
                auto topic_cb = std::bind(&TopicManager::onTopicRequest, _topic_manager.get(), std::placeholders::_1, std::placeholders::_2); // 服务回调
                _dispatcher->registerhandler<TopicRequest>(MType::REQ_TOPIC, topic_cb);                                                     // 将服务回调注册到调度器中
                //ELOG("完成注册中心::服务回调注册");

                _server = bitrpc::ServerFactory::create(port);
                auto message_cb = std::bind(&bitrpc::Dispatcher::onMessage, _dispatcher.get(), std::placeholders::_1, std::placeholders::_2); // 消息回调
                _server->setMessageCallback(message_cb);                                                                                      // 将消息回调注册到服务器中
                //ELOG("完成注册中心::消息回调注册");

                auto close_cb = std::bind(&TopicServer::onConnShutdown, this, std::placeholders::_1); // 关闭的回调
                _server->setCloseCallback(close_cb);                                                     // 将关闭回调注册到服务器中
                //ELOG("完成注册中心::关闭回调注册");
            }
            // 启动服务器
            void start()
            {
                ELOG("启动服务器!");
                _server->start();
            }

        private:
            void onConnShutdown(const BaseConnection::ptr &conn)
            {
                _topic_manager->onShutdown(conn); // 处理关闭连接
            }

        private:
            TopicManager::ptr _topic_manager; // 注册发现管理器
            Dispatcher::ptr _dispatcher;      // 调度器
            BaseServer::ptr _server;          // 服务器
        };
    }
}